package com.xxx.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.vo.CourseDetailVo;
import com.vo.CourseOrderConfirm;
import com.vo.CourseOrderConfirmItem;
import com.xxx.doc.CourseDoc;
import com.xxx.domain.*;
import com.xxx.dto.CourseDto;
import com.xxx.dto.PreCourseOrder2RedisDto;
import com.xxx.dto.StationMessage2MqDto;
import com.xxx.exception.GlobleBussnessException;
import com.xxx.feignclients.CourseDocFeignClient;
import com.xxx.feignclients.MediaFeignClient;
import com.xxx.mapper.CourseMapper;
import com.xxx.result.JSONResult;
import com.xxx.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.xxx.util.AssertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jh
 * @since 2025-09-03
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private ICourseService courseService;
    @Autowired
    private ICourseResourceService courseResourceService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseTeacherService courseTeacherService;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ITeacherService teacherService;

    @Autowired
    private CourseDocFeignClient courseDocFeignClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private MediaFeignClient mediaFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void addCourse(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseResource courseResource = courseDto.getCourseResource();
        List<Long> teacharIds = courseDto.getTeacharIds();
        //课程名称不能重复
        Course courseFromDB = selectByCouseName(course.getName());
        AssertUtil.isNull(courseFromDB, "课程名称已存在！");
        //插入课程
        course.setLoginId(1L); //TODO 登录用户ID,等做了登录功能后，从登录用户中获取用户ID
        course.setLoginUserName("yhptest1");
        course.setStatus(Course.STATUS_OFFLINE);
        List<Teacher> teachers = teacherService.selectBatchIds(teacharIds);
        List<String> names = teachers.stream().map(Teacher::getName).collect(Collectors.toList());
        //拼接老师名称
        String teacherNamesStr = String.join(",", names);
        course.setTeacherNames(teacherNamesStr);
        insert(course);
        //插入课程详情
        courseDetail.setId(course.getId());
        courseDetailService.insert(courseDetail);
        //插入课程营销信息
        courseMarket.setId(course.getId());
        courseMarketService.insert(courseMarket);
        //插入课程资源信息
        courseResource.setCourseId(course.getId());
        courseResourceService.insert(courseResource);
        //汇总表
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummaryService.insert(courseSummary);
        //老师中间表
        for (Long teacharId : teacharIds) {
            CourseTeacher courseTeacher = new CourseTeacher();
            courseTeacher.setCourseId(course.getId());
            courseTeacher.setTeacherId(teacharId);
            courseTeacherService.insert(courseTeacher);
        }
    }

    /**
     * 上线课程流程
     * 条件判断
     * 状态修改
     * 课程数据放到es
     * 发送站内信
     *
     * @param courseId
     */
    @Override
    @Transactional
    public void onlineCourse(String courseId) {
        //上线课程流程
        //条件判断
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, "待上线课程不存在！");
        AssertUtil.isEquals(Course.STATUS_OFFLINE, course.getStatus(), "课程已上线！");
        //状态修改
        course.setStatus(Course.STATUS_ONLINE);
        course.setOnlineTime(new Date());
        updateById(course);
        // 课程数据放到es
        CourseDoc courseDoc = new CourseDoc();
        //数据来自三张表
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        BeanUtils.copyProperties(course, courseDoc);
        BeanUtils.copyProperties(courseMarket, courseDoc);
        BeanUtils.copyProperties(courseSummary, courseDoc);
        JSONResult jsonResult = courseDocFeignClient.save(courseDoc);
        AssertUtil.isTrue(jsonResult.isSuccess(), jsonResult.getMessage());
        //发送站内信//todo
        log.info("发送站内信开始...");
        List<Long> userIdS = Arrays.asList(1L, 2L, 3L);
        String title = course.getName() + "课程上线啦!";
        String type = "系统消息";
        String content = String.format("亲爱的用户您好，最新课程 " +
                "<a href='http://localhost:6002/detail.html?courseId=%s'> %s </a> " +
                "发布啦，点击课程了解详情", courseId, course.getName());
        StationMessage2MqDto stationMessage2MqDto = new StationMessage2MqDto(title, content, type, userIdS);
        SendResult sendResult = rocketMQTemplate.syncSend("topic-message:station",
                JSONObject.toJSONString(stationMessage2MqDto));

        if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
            throw new RuntimeException("发送站内信失败！");
            //写方法去删除es数据//todo
        }
        log.info("发送站内信结束...");
    }

    /**
     * 参数校验
     * 条件判断
     * 根据课程查询几张表
     * feign调用视频信息
     *
     * @param courseId
     * @return
     */
    @Override
    public CourseDetailVo detail(Long courseId) {
        //参数校验
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course, "非法请求--课程不存在！");
        AssertUtil.isEquals(Course.STATUS_ONLINE, course.getStatus(), "非法请求--课程未上线！");
        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        List<CourseChapter> courseChapters = courseChapterService.listByCourseId(courseId);
        Map<Long, CourseChapter> ccMap = courseChapters.stream().collect(Collectors.toMap(CourseChapter::getId,
                courseChapter -> courseChapter));
        //发起feign调用,获取章节下的视频信息 参数课程ID
        JSONResult jsonResult = mediaFeignClient.getByCourseId(courseId);
        AssertUtil.isTrue(jsonResult.isSuccess(), jsonResult.getMessage());
        //List<MediaFile> mediaFiles = (List<MediaFile>) jsonResult.getData();
        String jsonString = JSONObject.toJSONString(jsonResult.getData());
        List<MediaFile> mediaFiles = JSONObject.parseArray(jsonString, MediaFile.class);
        for (MediaFile mediaFile : mediaFiles) {

            CourseChapter courseChapter = ccMap.get(mediaFile.getChapterId());
            if (courseChapter != null) {
                courseChapter.getMediaFiles().add(mediaFile);
            }
        }


        EntityWrapper<CourseTeacher> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id", courseId);
        List<CourseTeacher> courseTeachers = courseTeacherService.selectList(wrapper);
        List<Long> teacherIds =
                courseTeachers.stream().map(courseTeacher -> courseTeacher.getTeacherId()).collect(Collectors.toList());
        List<Teacher> teachers = teacherService.selectBatchIds(teacherIds);
        //根据课程查询几张表
        //feign调用视频信息
        return new CourseDetailVo(course, courseMarket, courseChapters, teachers, courseDetail, courseSummary);
    }

    /**
     * 获取订单页面的信息
     *
     * @param courseIds 1,6,9
     * @return
     */
    @Override
    public CourseOrderConfirm info(String courseIds) {
        String[] courseIdsArr = courseIds.split(",");
        TreeSet<String> treeSet = new TreeSet<>();
        for (String s : courseIdsArr) {
            treeSet.add(s);
        }
        List<Course> courses = selectBatchIds(treeSet);
        if (treeSet.size() != courses.size()) {
            throw new GlobleBussnessException("非法请求,课程不存在！");
        }
        //封装courseOrderConfirm
        CourseOrderConfirm courseOrderConfirm = new CourseOrderConfirm();
        BigDecimal totalAmount = new BigDecimal(0);
        for (Course course : courses) {
            AssertUtil.isEquals(Course.STATUS_ONLINE, course.getStatus(), "课程未上线！");
            CourseMarket courseMarket = courseMarketService.selectById(course.getId());
            //封装courseOrderConfirmItem订单明细
            CourseOrderConfirmItem ConfirmItem = new CourseOrderConfirmItem();
            ConfirmItem.setCourse(course);
            ConfirmItem.setCourseMarket(courseMarket);

            courseOrderConfirm.getItems().add(ConfirmItem);
            totalAmount = totalAmount.add(courseMarket.getPrice());
        }
        courseOrderConfirm.setTotalAmount(totalAmount);


        return courseOrderConfirm;
    }

    /**
     * @param orderNo
     * @return
     */
    @Override
    public CourseOrderConfirm killInfo(String orderNo) {
        Long longinId = 3L;
        //从Redis中获取预创订单课程信息
        String preCourseOrderKey = "preCourseOrder:" + longinId + ":" + orderNo;
        Object preCourseOrderObj = redisTemplate.opsForValue().get(preCourseOrderKey);
        AssertUtil.isNotNull(preCourseOrderObj, "订单不存在！");
        PreCourseOrder2RedisDto preCourseOrder2RedisDto =
                (PreCourseOrder2RedisDto) preCourseOrderObj;


        //查询出课程和课程营销信息
        Course course = selectById(preCourseOrder2RedisDto.getCourseId());
        AssertUtil.isNotNull(course, "课程不存在！");
        CourseMarket courseMarket = courseMarketService.selectById(preCourseOrder2RedisDto.getCourseId());
        AssertUtil.isNotNull(courseMarket, "课程不存在！");


        //封装courseOrderConfirm
        CourseOrderConfirm courseOrderConfirm = new CourseOrderConfirm();
        AssertUtil.isEquals(Course.STATUS_ONLINE, course.getStatus(), "课程未上线！");


        //封装courseOrderConfirmItem订单明细
        CourseOrderConfirmItem ConfirmItem = new CourseOrderConfirmItem();
        ConfirmItem.setCourse(course);
        ConfirmItem.setCourseMarket(courseMarket);
        courseMarket.setPrice(preCourseOrder2RedisDto.getTotalAmount());
        courseOrderConfirm.getItems().add(ConfirmItem);
        BigDecimal totalAmount = preCourseOrder2RedisDto.getTotalAmount();
        courseOrderConfirm.setTotalAmount(totalAmount);
        return courseOrderConfirm;
    }

    private Course selectByCouseName(String name) {
        EntityWrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name", name);
        return selectOne(wrapper);
    }
}
